package org.eu.base.io;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;


/**
 * 一个文件操作类,主要面对文本类文件,我不反对你用它来处理二进制文件,不过,后果自负
 * @author wenjianwzz
 * @version 0.5
 * @since wzz.eu 0.5 
 */
public class FileMan {

	String path;
	File file;
	RandomAccessFile randomFile;
	String fileEncoding="UTF-8";
	String encoding="UTF-8";
	
	/**
	 * 构造函数,如果文件不存在,它会创建一个,不过你要保证路径是正确的,这并不是一件困难的事情吧.
	 * @param path
	 */
	public FileMan(String path) {
		this.path = path;
		file = new File(path);
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			randomFile = new RandomAccessFile(file, "rw");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 构造函数,如果文件不存在,它会创建一个
	 * @param file
	 */
	public FileMan(File file) {
		this.path = file.getAbsolutePath();
		this.file=file;
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			randomFile = new RandomAccessFile(file, "rw");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 构造函数,如果文件不存在,它会创建一个,不过你要保证路径是正确的,这并不是一件困难的事情吧.
	 * 如果reCreate为true,则不管3721,会建立一个新的文件.
	 * @param path
	 * @param reCreate
	 */
	public FileMan(String path, boolean reCreate) {
		this.path = path;
		file = new File(path);
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}else if(reCreate){
			file.delete();
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			randomFile = new RandomAccessFile(file, "rw");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 将文本文件一行一行读出
	 * @return List<String>
	 * @see java.io.BufferedReader#readLine()
	 */
	public List<String> readLines() {
		InputStreamReader fr;
		List<String> list = new ArrayList<String>();
		try {
			fr = new InputStreamReader(new FileInputStream(file),fileEncoding);
			BufferedReader br = new BufferedReader(fr);
			String line = br.readLine();
			while (line != null) {
				list.add(line);
				line = br.readLine();
			}
			br.close();
			fr.close();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return list;
	}

	/**
	 * 将文件全部读出,这个是基于readLines的,只是在他们中间加上"\r\n"
	 * @return String
	 */
	public String readAll(){
		InputStreamReader fr;
		StringBuffer sb=new StringBuffer();
		try {
			fr = new InputStreamReader(new FileInputStream(file),fileEncoding);
			BufferedReader br = new BufferedReader(fr);
			String line = br.readLine();
			while (line != null) {
				sb.append(line+"\r\n");
				line = br.readLine();
			}
			br.close();
			fr.close();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return sb.toString();
	}
	
	/**
	 * 在文件末尾添加
	 * @param content
	 */
	public void append(String content) {
		try {
			long fileLength = randomFile.length();
			randomFile.seek(fileLength);
			randomFile.write(content.getBytes(encoding));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 覆写文件
	 * @param content
	 */
	public void overWrite(String content){
		try {
			randomFile.setLength(0);
			randomFile.write(content.getBytes(encoding));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 关闭	
	 */
	public void close(){
		try {
			if(randomFile!=null)
				randomFile.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取文件编码,事实上这并不是文件真正的编码,只是规定了用什么编码去读写文件
	 * @return FileEncoding
	 */
	public String getFileEncoding() {
		return fileEncoding;
	}

	/**
	 * 设置读写文件的编码
	 * @param fileEncoding
	 * @return this
	 */
	public FileMan setFileEncoding(String fileEncoding) {
		this.fileEncoding = fileEncoding;
		return this;
	}

	/**
	 * 设置写入String的编码
	 * @param encoding
	 * @return this
	 */
	public FileMan setEncoding(String encoding) {
		this.encoding = encoding;
		return this;
	}
	
	/**
	 * 获取文件引用
	 * @return this.file
	 */
	public File getFile(){
		return this.file;
	}
	
	/**
	 * 
	 * @return RandomAccessFile
	 */
	public RandomAccessFile getRandomAccessFile(){
		return this.randomFile;
	}
}